﻿using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using BPM.Web.Shared.Interceptor;
namespace BPM.Web.Shared.Extensions;

/// <summary>
/// 添加和使用HttpClientInterceptor的扩展方法。
/// </summary>
public static class HttpClientInterceptorExtension
{
    private static readonly FieldInfo? s_handlerField = typeof(HttpMessageInvoker)
        .GetField("_handler", BindingFlags.Instance | BindingFlags.NonPublic);

    public static void AddHttpClientInterceptor(this IServiceCollection services)
    {
        services.TryAddSingleton(services =>
        {
            if (s_handlerField != null)
            {
                var httpClient = default(HttpClient);
                try
                {
                    httpClient = services.GetService<HttpClient>();
                }
                catch (InvalidOperationException e) when (e.Source == "Microsoft.Extensions.DependencyInjection" && e.HResult == -2146233079)
                {
                }

                if (httpClient != null)
                {
                    httpClient.EnableIntercept(services);
                }
            }

            return new HttpClientInterceptor();
        });

        services.TryAddSingleton(services =>
             (TokenInterceptor)(services.GetService<TokenInterceptor>()
             ?? new HttpClientInterceptor()));
    }

    public static HttpClient EnableIntercept(this HttpClient httpClient, IServiceProvider services)
    {
        if (s_handlerField?.GetValue(httpClient) is HttpMessageHandler baseHandler && baseHandler is not HttpClientInterceptorHandler)
        {
            var interceptorHandler = new HttpClientInterceptorHandler(services, baseHandler);
            s_handlerField.SetValue(httpClient, interceptorHandler);
        }
        return httpClient;
    }
}

